Skip to content

feat(avro): apply column default values when reading missing fields#800

Open
huan233usc wants to merge 2 commits into
apache:mainfrom
huan233usc:feat/default-values-read-avro
Open

feat(avro): apply column default values when reading missing fields#800
huan233usc wants to merge 2 commits into
apache:mainfrom
huan233usc:feat/default-values-read-avro

Conversation

@huan233usc

@huan233usc huan233usc commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

What

Part 3 of 4 of Iceberg v3 column default-value support (POC #731), built on the
schema layer (#746) and the Parquet read path (#792).

When a column is present in the read (table) schema but absent from an Avro data
file — because the column was added after those rows were written — fill it with
the column's v3 initial-default instead of null.

Changes

  • Avro projection (avro_schema_util.cc): when a field is missing from the
    file and carries an initial-default, project it as
    FieldProjection::Kind::kDefault, mirroring the generic / Parquet paths.
  • Avro decode (avro_data_util.cc, avro_direct_decoder.cc): materialize
    the kDefault branch through an Avro-local AppendDefaultToBuilder helper.
    It reuses the shared ToArrowScalar conversion, while keeping Avro's
    row-by-row ArrayBuilder append behavior out of the shared Arrow utility.

Tests

  • avro_data_test: AppendDefaultToBuilder appends a value and casts to the
    builder type; AppendDatumToBuilder fills missing required and optional
    default fields.
  • avro_test: end-to-end — write an Avro file with an old schema, then read it
    through ReaderFactoryRegistry with an evolved schema carrying defaults
    (ReadMissingFieldsWithDefaults).

Stack

  1. feat(schema): represent, serialize and validate v3 column default values (1/4) #746 — schema: represent / serialize / validate (merged)
  2. feat(parquet): apply column default values when reading missing fields (2/4) #792 — read path: Parquet (merged)
  3. this PR — read path: Avro
  4. schema evolution: addColumn / updateColumnDefault (feat: support v3 column default values in UpdateSchema (3/4) #793)

Draft while the earlier PRs in the stack settle.

@huan233usc
huan233usc force-pushed the feat/default-values-read-avro branch from 75bd63f to 950f4dc Compare July 12, 2026 21:10
@huan233usc huan233usc changed the title feat(avro): apply column default values when reading missing fields (3/4) feat(avro): apply column default values when reading missing fields Jul 20, 2026
…3/4)

When a column is present in the read schema but missing from an Avro data file
(written before the column existed), fill it with the column's v3
initial-default instead of null. Reuses the shared arrow/literal_util
materializer (merged in apache#792) and adds AppendDefaultToBuilder for the row-by-row
Avro decode paths, plus a kDefault projection branch in the Avro schema/data
projection.

Part 3 of the v3 column-default-values work (POC apache#731), built on the schema
support in apache#746 and the Parquet read path in apache#792.
Row-oriented Avro decode needs per-builder appends, while Parquet uses
batch MakeDefaultArray. Share ToArrowScalar only; don't put the Avro
shape into the shared arrow literal util.
@huan233usc
huan233usc force-pushed the feat/default-values-read-avro branch from 0961b90 to 9e1605f Compare July 20, 2026 04:38
@huan233usc
huan233usc marked this pull request as ready for review July 20, 2026 04:39
@manuzhang manuzhang added this to the 0.4.0 milestone Jul 21, 2026
@manuzhang
manuzhang requested a review from Copilot July 22, 2026 04:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Avro read-path support for Iceberg v3 initial-default column defaults, ensuring that when projected (table) schema fields are missing from older Avro files, readers materialize the specified defaults instead of null.

Changes:

  • Avro schema projection: project missing fields with initial-default as FieldProjection::Kind::kDefault.
  • Avro decode paths (generic + direct): materialize kDefault by appending the literal default into Arrow builders via a new Avro-local AppendDefaultToBuilder.
  • Tests: add unit coverage for default appends and an end-to-end Avro read test exercising schema evolution with defaults.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/iceberg/avro/avro_schema_util.cc Projects missing fields with initial-default as kDefault.
src/iceberg/avro/avro_data_util.cc Implements and uses AppendDefaultToBuilder to materialize kDefault during generic Avro decoding.
src/iceberg/avro/avro_direct_decoder.cc Materializes kDefault during direct decoding into Arrow builders.
src/iceberg/avro/avro_data_util_internal.h Exposes AppendDefaultToBuilder for reuse across Avro decode implementations.
src/iceberg/test/avro_data_test.cc Adds unit tests covering default materialization behavior.
src/iceberg/test/avro_test.cc Adds end-to-end test for reading missing fields with defaults using an evolved schema.

Comment on lines +512 to +514
ICEBERG_ASSIGN_OR_RAISE(std::shared_ptr<::arrow::Scalar> scalar,
arrow::ToArrowScalar(literal, ::arrow::default_memory_pool()));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants